EJEMPLOS DE UTILIZACIN DE LAS LLAMADAS AL SISTEMA DEL SUBSISTEMA DE FICHEROS EN UNIX

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#include <string.h>

int main(void)
{
   int handle;
   char string[40];
   int length, res;

/* Crea un fichero llamado "TEST.$$$" en el directorio de trabajo y escribe en Jl una cadena.  Si "TEST.$$$" existe ya, ser< sobreescrito. */

   if ((handle = open("/users/TEST.$$$", O_CREAT | O_TRUNC,0700))== -1)
   {
      printf("open");
      exit(1);
   }

   strcpy(string, "Hello, world!\n");
   length = strlen(string);

   if ((res = write(handle, string, length)) != length)
   {
      printf("write");
      exit(1);
   }
   printf("Escritos %d bytes en el archivo.\n", res);

   close(handle);
   return 0;
}

	-----------------------------
/* Lectura y escritura de ficheros */
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#define TAM_BUF 128

void entrada(char *buf, int fd1);
void mostrar(char *buf, int fd2);

void main(void)
{
	char buf(TAM_BUF);
	int fd1, fd2;

	if((fd1=open("/users/m1306854/prueba", O_WRONLY))==-1){
		printf("No se puede abrir el archivo\n");
		exit(1);
	}
	entrada(buf, fd1);

	close(fd1);

	if((fd2=open("prueba", O_RDONLY))==-1){
		printf("No se puede abrir el archivo\n");
		exit(1);
	}
	mostrar(buf, fd2);
	close(fd2);
}


void entrada(char *buf, int fd1)
{
	register int t;
	do{
		for(t=0; t<TAM_BUF; t++)
			buf[t]='\0';
		gets(buf);
		if(write(fd1, buf, TAM_BUF) != TAM_BUF){
			printf("Error de escritura en el archivo\n");
			exit(1);
		}
	}while (strcmp(buf, "salir"));
}


void mostrar(char *buf, int fd2)
{
	for(;;){
		if(read(fd2, buf, TAM_BUF)==0)
			return;
		printf("%s\n", buf);
	}
}
	---------------------------------
/* Lectura de un directorio */
#include<sys/dir.h>
#include<stdio.h>
int directorio(path);
char *path;
{
struct directx{
	ino_t d_ino;
	char d_name[DIRSIZ +1];
	}dlink;
int fd,nread;
char dname[DIRSIZ +1];
if ((fd=open(path,0))== -1)
   {	perror(path);
	exit(1);  }
dlink.d_name[DIRSIZ+1]='\0';
while ((nread=read(fd,&dlink,sizeof(struct directx)))==sizeof(struct directx))){
	if (dlink.d_ino==0)
		dname="------------sin uso----------";
	else
		strcpy (dname,dlink.d_name);
	printf("%-14s%4d\n",dname,dlink.d_ino);
	}
}

	-------------------------------
/* Creaci\n de un directorio con mknod */

#define ERROR -1
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

main(int argc, char **argv)
{  if (argc!=2)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }
	if (mknod(argv[1],S_IFDIR | 0755,0)==ERROR)
	  {  errorSistema(argv[1]);
		  return(2);   }
	return 0;
}
	----------------------------------
/* Ejemplo de la llamada al sistema link */
#define ERROR -1
#include <stdio.h>

main(int argc, char **argv)
{  if (argc!=3)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }
	if (link(argv[1],argv[2])==ERROR)
	  {  errorsistema("link");
		  return(2);   }
	return 0;
}
	---------------------------------
/* Ejemplo de la llamada al sistema chown */
#define ERROR -1
#include <stdio.h>

main(int argc, char **argv)
{  int uid,gid;
if (argc!=4)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }
uid=atoi(argv[1]);
gid=atoi(argv[2]);
if (chown(argv[3],uid,gid)==ERROR)
	  {  errorSistema("chown");
		  return(3);   }
	return 0;
}
	----------------------------------
/* Ejemplo de la llamada al sistema utime */
#define ERROR -1
#include <stdio.h>
#include <sys/types.h>

struct utimbuf {
			time_t  acceso_time;
			time_t modifi_time;
			}  *times;

main(int argc, char **argv)
{  long int ahora;
if (argc!=2)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }

if ((ahora=time(0))==ERROR)
	  {  errorSistema("time");
		  return(2);   }
times=(struct utimbuf*)malloc(sizeof(struct utimbuf));
times->acceso_time=ahora;
times->modifi_time=ahora;
if(utime(argv[1],times)==ERROR)
	{  errorSistema ("utime");
		return(3);  }
	return 0;
}
	---------------------------------
/* Ejemplo de la llamada al sistema stat */
#define ERROR -1
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

main(int argc, char **argv)
{  struct stat buffer;
if (argc!=2)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }

if (stat(argv[1],&buffer)==ERROR)
	  {  errorSistema("stat");
		  return(2);   }
printf("Datos del i-nodo del fichero : %s-1n",argv[1]);
printf("==============================\n");
printf("Ndmero del i-nodo  = %d \n",buffer.st_ino);
printf("Tipo de fichero  = ");
switch(buffer.st_mode & S_IFMT)
{  case S_IFDIR : printf("Directorio \n");  break;
   case S_IFREG : printf("Fichero regular \n");  break;
   case S_IFCHR : printf("Dispositivo de tipo car<cter \n");  break;
   case S_IFBLK : printf("Dispositivo de tipo bloque \n");  break;
   case S_IFIFO : printf("TuberRa nominada \n");  break;
   default : printf("tipo desconocido\n");  }
printf("Sus permisos son = ");
/* Permisos para el propietario */
switch(buffer.st_mode & 0000700) {
  case 0700 : printf("rwx "); break;
  case 0600 : printf("rw- "); break;
  case 0500 : printf("r-x "); break;
  case 0400 : printf("r-- "); break;
  case 0300 : printf("-wx "); break;
  case 0200 : printf("-w- "); break;
  case 0100 : printf("--x "); break;
  case 0000 : printf("--- "); break;   }
/* Permisos para el grupo */
switch(buffer.st_mode & 0000070) {
  case 0070 : printf("rwx "); break;
  case 0060 : printf("rw- "); break;
  case 0050 : printf("r-x "); break;
  case 0040 : printf("r-- "); break;
  case 0030 : printf("-wx "); break;
  case 0020 : printf("-w- "); break;
  case 0010 : printf("--x "); break;
  case 0000 : printf("--- "); break;   }
/* Permisos para los dem<s */
switch(buffer.st_mode & 0000007) {
  case 0007 : printf("rwx "); break;
  case 0006 : printf("rw- "); break;
  case 0005 : printf("r-x "); break;
  case 0004 : printf("r-- "); break;
  case 0003 : printf("-wx "); break;
  case 0002 : printf("-w- "); break;
  case 0001 : printf("--x "); break;
  case 0000 : printf("--- "); break;   }
printf("Ndmero de links  = %d\n", buffer.st_nlink);
printf("Propietario UID  = %d\n",buffer.st_uid);
printf("Grupo       gid  = %d\n", buffer.st_gid);
printf("Ndmero de Device = %d\n",buffer.st_rdev);
printf("TamaZo en bytes  = %d\n", buffer.st_size);
printf("Valor de st_atime= %s\n",ctime(&buffer.st_atime));
printf("Valor de st_mtime= %s\n",ctime(&buffer.st_mtime));
printf("Valor de st_ctime= %s\n",ctime(&buffer.st_ctime));
	return 0;
}
	---------------------------------
/* Ejemplo de la llamada al sistema ustat */

#define ERROR -1

#include <stdio.h>
#include <sys/types.h>
#include <ustat.h>

main(int argc, char **argv)
{  int numero;
struct stat buffer;
if (argc!=2)
	  { printf("((( Ndmero de par<metros incorrecto !!!\n");
		 return 1;  }

numero=atoi(argv[1]);
if (ustat(numero,&buffer)==ERROR)
	  {  errorSistema("ustat");
		  return(2);   }
printf("Datos del device ndmero : %s\n",argv[1]);
printf("==============================\n");
printf("Total de bloques libres = %d \n",buffer.f_tfree);
printf("Total de i-nodos libres = %d\n", buffer.f_tinode);
printf("Nombre del File System  = %d\n",buffer.f_fname);
printf("Nombre del directorio \n");
printf("    sobre el que se monta= %s\n",buffer.f_fpack);
	return 0;
}
	---------------------------------
/* Ejemplo de la llamada al sistema dup */
#define ERROR -1
#include <stdio.h>
#include <fcntl.h>

main(int argc, char **argv)
{  long int fd1,fd2;
if ((fd1=open("DATOS",O_RDONLY))==ERROR)
	  { errorsistema ("open");
		 return 1;  }
if ((fd2=dup(fd1))==ERROR)
	  {  errorsistema("dup");
		  return(2);   }
printf("Valor del primer descriptor de archivo : %ld\n",fd1);
printf("Valor del segundo descriptor de archivo: %ld\n",fd2);
close(fd1);
close(fd2);
return 0;
}
	---------------------------------
/* Ejemplo de la llamada al sistema fstat */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#define STDIN 0
#define ERROR -1


int main(argc, argv)
int argc;
char *argv[];
{
	int rc=0, i;
	struct stat statb;
	if(argc==1)
		if(fstat(STDIN, &statb)==ERROR){
			perror("stdin");
			rc=1;
		} else presenta("stdin", &statb);
	else
		for(i=1; i<argc; i++)
			if(stat(argv[i], &statb)==ERROR){
				perror(argv[i]);
				rc=1;
			} else presenta(argv[i], &statb);
	exit(rc);
}

int presenta(nombre, sp)
char nombre;
struct stat *sp;
{
	extern char *ctime();

	printf("Fichero: %s\n", nombre);
	printf("Ndmero de nodo-i: %d\n", sp->st_ino);
	printf("Modo: %o\n", cambia(sp->st_mode));
	printf("Enlaces: %d\n", sp->st_nlink);
	printf("ID del usuario: %d\n", sp->st_uid);
	printf("ID de grupo: %d\n", sp->st_gid);
	printf("TamaZo: %ld\n", sp->st_size);
	printf("Ultimo acceso: %s\n", ctime(&sp->st_atime));
	printf("Ultima modificaci\n: %s\n", ctime(&sp->st_mtime));
	printf("Creaci\n: %s\n", ctime(&sp->st_ctime));
}

char cambia(modo)
int modo;
{
	if((modo & 512)==1)
		return('r');
}
	--------------------------
/* Ejemplo de la llamada al sistema access */
#include <stdio.h> 	/* cabecera de e/s estandar */
#include <sys/access.h>	/* accesibilidad de los archivos */
main(int argc,char *argv[])
{
	if (argc==1)
	  printf("ERROR: debe especificarse un archivo \n"),
	  exit(1);
	if (access(argv[1],00)!=0)
		printf("%s: no existe \n",argv[1]);
	if (access(argv[1],04)==0)
		printf("%s: Tiene permiso de lectura \n",argv[1]);
	if (access(argv[1],02)==0)
		printf("%s: Tiene permiso de escritura \n",argv[1]);
	if (access(argv[1],01)==0)
		printf("%s: Tiene permiso de ejecucion \n",argv[1]);
}
	---------------------------
d#include <stdio.h> /* cabecera de e/s estandar */
#include <fcntl.h> /* atributos de ficheros */
#include <sys/mode.h> /* valores de modo de ficheros */
#include <sys/types.h> /* definiciones de tipos */
#include <unistd.h> /* constantes de lseek */
main()
{
	int fd;    
	int fd1;
	int ret;
	int retc;
	short i;
	char line[31];
	retc=chdir("/home/domingo");
	/* abre el fichero mifichero para lectura y escritura */
	if ((fd=open("michero",O_RDWR,0644))!=0) {
		/* crea fichero nuevofich con acceso de lectura al grupo */
		retc=umask(S_IROTH);
		if ((fd1=creat("nuevofich",0644))!=0) {
			/* salta 5 primeras entradas de michero */
			ret=lseek(fd,(5*sizeof(line)),SEEK_SET);
			/* lee 5 siguientes entradas de michero
			   y las escribe en nuevofich */
			for (i=0;i<5;i++) {
				retc=read(fd,line,sizeof(line));
				retc=write(fd1,line,sizeof(line));
			}
			close(fd1);
		}
		close(fd);
		chmod("mifichero",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	}
	else
		perror ("fichero mifichero inexistente");
}
	------------------------------
/* Establecimiento de bloqueos a ficheros */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#ifdef SEEK_SET
#   define SEEK_SET 0
#endif

#define EQ(str1,str2) (strcmp(str1,str2)==0)
#define FICHERO "tmp"

sin_bloqueo()
{}

con_bloqueo(fd,orden)
int fd, orden;
{
	struct flock cerrojo;
	cerrojo.l_type=orden;
	cerrojo.l_whence=SEEK_SET;
	cerrojo.l_start=0;
	cerrojo.l_len=0;

	if (fcntl(fd,F_SETLKW,&cerrojo)==-1)
		{
			perror("fcntl");
			exit (-1);
		}
}

main(argc,argv)
int argc;
char *argv[];
{
	int fd;
	int numero,i,j;
	int (*bloquear)();
	if (argc==1)
		bloquear=sin_bloqueo;
	else if (argc==2 && EQ(argv[1],"-b"))
		bloquear=con_bloqueo;
		else{
			fprintf (stderr,"Forma de uso: %s [-b]\n",argv[0]);
			exit (-1);
		}

	if ((fd=open(FICHERO,O_RDWR|O_CREAT,0644))==-1)
	{
		perror(FICHERO);
		exit (1);
	}

	if (read(fd,&numero,sizeof(numero))!=sizeof(numero))
	{
		numero=0;
		write (fd,&numero,sizeof(numero));
	}

	for (i=0;i<10;i++){
		lseek(fd,0L,SEEK_SET);
		(*bloquear)(fd,F_WRLCK);
		read (fd,&numero,sizeof(numero));
		++numero;
		sleep(1);
		lseek(fd,0L,SEEK_SET);
		write (fd,&numero,sizeof(numero));
		printf("PID=%d, nro =%d\n",getpid(),numero);
		(*bloquear)(fd,F_UNLCK);
	}
	close (fd);
}
	------------------------------------
#include <stdio.h>	/* e/s estandar */
#include <fcntl.h>	/* atributos de fichero */
#include <sys/mode.h>	/* valores de modos de fichero */
#include <sys/types.h>	/* definiciones de tipos */
#include <unistd.h>	/* constantes lseek */
main()
{
	int fd;
	int fd1;
	int fd2;
	int ret;
	int retc;
	short i;
	char line[31];
	/* abre archivo mifchero para lectura-escritura */
	if ((fd=open("mifichero",O_RDWR,0644))!=0) {
		/* crea archivo nuevofich con acceso de lectura-escritua */
		if ((fd1=creat("nuevofich",0666))!=0) {
			close(1);
			/* escribe stdout en nuevofich	*/
			fd2=fcntl(fd1,F_DUPFD,0);
			printf("NOTA: esta lista es revision de mifichero \n");
			/* salta 5 primeras entradas de michero */
			ret=lseek(fd,(5*sizeof(line)),SEEK_SET);
			/* lee 5 siguientes entradas de michero
			   y las escribe eb nuevofich */
			for (i=0;i<5;i++) {
				retc=read(fd,line,sizeof(line));
				retc=write(fd1,line,sizeof(line));
			}
			close(fd1);	
		}
		close(fd);
	}
	else
		perror ("fichero mifichero inexistente");
}
	--------------------------------
#include <stdio.h>  		/* e/s estandar	*/
#include <sys/utsname.h> 	/* informacion del sistema	*/
#include <sys/types.h>		/* definicion de tipos	*/
struct utsname *nptr;/* ptr. a la estr. de informacion del sistema */
main()
{
	int ret;
	nptr=(struct utsname *)malloc(sizeof(struct utsname));
/* asigna espacio para la estr. de informacion del sistema	*/
	printf("mi id de usuario real es %d\n",getuid());
	printf("mi id de usuario efectivo es %d\n",geteuid());
	printf("mi id de grupo efectivo es %d\n",getegid());
	ret=setuid(239);/* ojo a posibilidades de asignac. del euid Los codigos de retorno son 0 si es correcto, -1 si hay error */
	printf("mi id de usuario es cambiado a %d\n",geteuid());
	printf("mi id de grupo real es %d\n",getgid());
	ret=setegid(211); 	/* ojo a posibilidades de asignac.del egid. Los codigos de retorno son 0 si es correcto, -1 si hay error */
	printf("mi id de grupo efectivo es cambiado a %d\n",getegid());
	ret=uname(nptr);
/* uname devuelve un numero no negativo si correcto, -1 si hay error. Se imprime solo el nombre del sistema de la estructura */
	printf("El nombre del sistema actual es %s. \n", nptr->sysname);
}
	-------------------------------
/* Ejemplo de las llamadas al sistema link y unlink */
#include <stdio.h> /* cabecera de e/s estandar */
#include <sys/types.h>	/* definicion de tipos */
#include <sys/stat.h> /* estado de fichero */
struct stat *stsptr;
main(int argc, char *argv[])
{
	int retc;
	stsptr=(struct stat *)malloc(sizeof(struct stat));
	retc=chdir("/home/lda");
	sync();
	retc=stat(argv[1],stsptr);
	printf("num. de enlaces para %s es: %d.\n", argv[1], stsptr->st_nlink);
	printf("enlazando con fichero %s...\n", argv[2]);
	link(argv[1],argv[2]);
	retc=stat(argv[2],stsptr);
	printf("num. de enlaces ahora para %s es: %d.\n", argv[2], stsptr->st_nlink);
	printf("suprimiendo el enlace...\n");
	unlink(argv[2]); 
	retc=stat(argv[1],stsptr);
	printf("num. de enlaces vuelve a ser: %d.\n", stsptr->st_nlink);
}
	-------------------------------
/* Escribir el comando pwd */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#define LARMAX 256
char ref[LARMAX];
struct stat buf1,buf2; /* para nodos-i*/
int d;
int encontrado;
struct direct catal; /* para contenido de los directorios*/
int n=sizeof(catal);/* tamaZo de el item catal*/
int indice=LARMAX;

main()
{ ref[LARMAX] ='\0';
    for (;;)
     { if (stat(".",&buf1) <0)
         {fprintf(stderr,"error en stat(.)\n");
           exit(1);}
       if ((d=open("..",0)) == -1 )
         {fprintf (stderr,"error de apertura de..\n");
           exit(2);}
       if (stat("..",&buf2) <0 )
         {fprintf(stderr,"error en stat(..)\n") ;
         exit(3);}
       if (chdir("..")<0)
         {fprintf(stderr,"error sobre chdir(..)\n");
           exit(4); }
       if (buf1.st_dev == buf2.st_dev)
/* si los directorios . y .. estan en el mismo disco l\gico */
         { if(buf1.st_ino ==buf2.st_ino) escribir();
        /*si est)n en el mismo disco, pero son diferentes */
           encontrado=0;
           while (!encontrado && read(d,(char *) &catal,n) == n)
              if (catal.d_ino == buf1.st_ino) encontrado = 1;
              if (!encontrado)
                 {fprintf(stderr,"error de lectura en ..\n");
                   exit(5);}          }
       else
          { encontrado =0;
            while (!encontrado && read(d,(char *)&catal,n) == n)
              { stat(catal.d_name,&buf2);
                if (buf2.st_dev == buf1.st_dev) encontrado=1; }
            if (!encontrado)
                 {fprintf(stderr,"error de lectura en ..\n");
                  exit(5);}  }
        close(d);
        tratamiento();
        }
}

tratamiento()
{ static int n;
n = strlen(catal.d_name);
if ((indice -= n) < 0 )
   { fprintf(stderr,"referencia demasiado larga\n");
   exit(6); }
strncpy(ref+(indice--),catal.d_name,n);
strncpy(ref+indice,"/",1);
}

escribir()
/* escribe la cadena ref+indice*/
{
if(indice == LARMAX) printf("/");
else   printf("%s\n",ref+indice);
exit(0);
}
	--------------------------------
/* Ejemplo de la llamada al sistema statfs */

#include <stdio.h>	/* cabecera de e/s estandar */
#include <sys/statfs.h>	/* sistema de ficheros */
#include <sys/stat.h>	/* estado del fichero */

struct statfs *sfsptr;
struct stat *stsptr;

main(int argc, char *argv[])
{
sfsptr=(struct statfs *)malloc(sizeof(struct statfs));
stsptr=(struct stat *)malloc(sizeof(struct stat));
if (argc==1) printf("ERROR: debe especificarse un fichero.\n"), exit(1);
if (stat(argv[1],stsptr) != 0)
		printf("ERROR en llamada de stat.\n"), exit(1);
printf("num. de enlaces: %d\n",stsptr->st_nlink);
printf("propietaro: %d\n",stsptr->st_uid);
printf("ultimo acceso: %d\n",stsptr->st_atime);
if (statfs(argv[1],sfsptr) != 0)
		printf("ERROR en llamada de statfs.\n"), exit(1);
printf("nombre del sistema de ficheros: %s\n",sfsptr->f_fname);
printf("total de bloques de datos: %d\n",sfsptr->f_blocks);
printf("bloques libres: %d\n",sfsptr->f_bfree);
}
	----------------------------
/* Llamada access: Chequeo de permisos de un fichero
par<metros: nombre del fichero y permisos a chequear */

#define ERROR -1
#include <stdio.h>
#include <errno.h>

main(argc,argv)
char argc;
char *argv[];
{ int permisos;
if (argc!=3)
   { printf ("((( Ndmero de par<metros incorrecto !!!\n");
   return(1); }
permisos=atoi(argv[2]);
if (permisos>7)
   { printf("Valor %d demasiado grande : de 0 a 7\n");
   return(2); }
if (access(argv[1],permisos)==ERROR)
   { if (errno=EACCES)
      printf("Modo %d NO permitido sobre el fichero %s\n",
		permisos,argv[1]);
      else perror(argv[1]);
      return(3); }
printf("Modo %d SI permitido sobre el fichero %s\n",
	permisos,argv[1]);
return(0);
}
	---------------------------------
/* Bloqueo de archivos */

#define LOCKDIR "/tmp/"
#define MAXTRIES 3
#define NAPTIME 5

int lock (name) /* conseguir cierre */
char *name;
{ char *path, *lockpath();
int fd tries;
extern int errno;
path=lockpath(name);
tries=0;
while ((fd=creat(path,0))==-1 && errno==EACCES) {
	if (++tries>=MAXTRIES) return (0);
	sleep (NAPTIME); }
if (fd==-1||close(fd)==-1) syserr("lock");
return(1);
}

void unlock(name) /* liberar */
char *name;
{ char *lockpath();
if (unlink(lockpath(name))==-1) syserr("unlock");
}

static char *lockpath(name)
/* generar un fichero para el bloqueo */
char *name;
{ static char path[20];
char *strcat();
strcpy(path,LOCKDIR);
return(strcat(path,name));
}
	------------------
#define BUFSIZE 512

void copy2(from,to) /* copia de ficheros */
char *from,*to;
{ int fromfd,tofd,nread,nwrite,n;
char buf[BUFSIZE];
if((fromfd=open(from,0))==-1) syserr(from);
if((tofd=creat(to,0666))==-1) syserr(to);
while((nread=read(fromfd,buf,sizeof(buf)))!=0) {
  if (nread==-1) syserr("read");
  nwrite=0;
  do {
     if ((n=write(tofd,&buf[nwrite],nread-nwrite))==-1)
	syserr("read");
     nwrite+=n;
     } while(nwrite < nread); }
if (close(fromfd)==-1||close(tofd)==-1)
  syserr("close");
}
	-----------------------------
/* Conjunto de subrutinas que manejan los buffers autom<ticamente */
 STREAM.H

#define SENOMEN 1001
#define SEINVAL 1002
#define BUFSIZE 512

typedef struct {
  int fd; /*descriptor de archivo */
  char dir; /* direccion: r o w */
  int total; /* caracteres totales en buf */
  int next; /* siguiente caracter en buf */
  char buf[BUFSIZE];
  } STREAM;

STREAM *Sopen();
int Sgetc();
BOOLEAN Sputc();
BOOLEAN Sclose();


#include "stream.h"
#include "stdio.h"

extern int errno;
STREAM *Sopen(path,dir) /*abrir corriente*/
char *path, *dir;
{ STREAM *z;
int fd,flags;
char *malloc();

switch(dir[0]){
  case 'r':
    flags=O_RDONLY;
    break;
  case 'w':
    flags=O_WRONLY|O_CREAT|O_TRUNC;
    break;
  default:
    errno=SEINVAL;
    return(NULL); }
z->fd=fd;
z->total=z->next=0;
return(z);
}

static BOOLEAN readbuf(z) /* llenar el buffer */
STREAM * z;
{ switch (z->total=read(z->fd,z->buf,sizeof(z->buf)))
    { case -1: return (FALSE);
    case 0: errno=0;
	    return(FALSE);
    default: z->next=0;
	     return(TRUE); }
}

static BOOLEAN writebuf(z) /* vaciar el buffer */
STREAM * z:
{ int n,total;
total=0;
while(total < z->next) {
  if ((n=write(z->fd,&z->buf[total],z->next-total))==-1)
     return(FALSE);
  total +=n; }
z->next=0;
return (TRUE);
}

int Sgets(z) /* leer car<cter */
STREAM * z;
{ int c;
if (z->next >= z->total && !readbuf(z))
   return(-1);
return (z->buf[z->next++] & 0377);
}

BOOLEAN Sputc (z,c) /* escribir un car<cter */
STREAM *z;
char c;
{ z->buf[z->next++]=c;
if (z->next>=sizeof(z->buf)) return (writebuf(z));
return(TRUE);
}

BOOLEAN Sclose(z) /* cerrar la corriente */
STREAM *z;
{ int fd;
if (z->dir=='w'&& !writebuf(z)) return(FALSE);
fd=z->fd;
free(z);
return(close(fd) !=-1);
}

/* recodificaci\n de la rutina de copia de ficheros
utilizando este paquete */
void copy(from,to)
char *from,*to;
{ STREAM *stfrom,*stto;
int c;
extern int errno;
if (stfrom=Sopen (from,"r"))==NULL=) syserr(from);
if ((stto=Sopen(to,"w"))==NULL) syserr(to);
while ((c=Sgetc(stfrom)) !=-1)
  if (!Sputc(stto,c)) syserr("Sputc");
if (errno!=0) syserr("Sgetc");
if (!Sclose(stfrom)|| !Sclose(stto)) syserr("Sclose");
}
	---------------------------------
/* Imprime un fichero hacia atr<s lRnea a lRnea */

void backward( path)
char *path;
{ char s[101], c;
int i,fd,nread;
long where,lseek();
if ((fd=open(path,0))==-1) syserr(path);
if((where=lseek(fd,-1L,2))==-1) syserr("lseek");
i=sizeof(s)-1;
s[i]='\0';
while ((nread=read(fd,&c,1))==1)
  { if(c=='\n')
      { printf("%s",&s[i]);
      i=sizeof(s)-1; }
  if(i==0) fatal("linea demasiado larga");
  s[--i]=c;
  if (where=lseek(fd,-2L,1))==-1) syserr("lseek"); }
switch(nread) {
  case 0: fatal ("end-of-file");
  case -1: syserr("read"); }
printf ("%s",&s[i]);
if (close(fd)==-1) syserr("close");
}
	----------------------------
/* PequZa utilidad para el manejo de archivos */
#define ERROR -1
#define CIERTO 1
#define FALSO 0
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

main()
{ setbuf(stdout,NULL);
help();
mainloop();
}

static void mainloop() /* procesador de ordenes */
{ char path[50], cmd[10], shcmd[100];
while(1)
 { prompt("Orden: ",cmd);
 if (strlen(cmd)>1) cmd[0]='\1'; /*fuerza el mensaje de comando
desconocido*/
 switch(cmd[0])
 { case '\0':
   case 'q': exit(0);
   case 'a':
   case 'm': chtime(path,cmd[0]); continue;
   case 'f': prompt("Fichero: ",path);
	     if (access(path,0)==-1)
		  { printf("%s No existe\n",path); continue; }
	     status(path); continue;
   case 'o': chowner(path); continue;
   case 'p': chperms(path); continue;
   case 's': status(path); continue;
   case '!': prompt("Orden SHELL: ", shcmd);
	     system (shcmd); continue;
   case '?': help(); continue;
   default: printf("Orden desconocida. ");
	    printf("Pulse >?< para pantalla de ayuda\n");
	    continue; }  }
}

static void help() /*Pantalla de ayuda */
{ printf("   *** Ordenes de la utilidad UTOOLS ***\n");
printf("   =====================================\n");
printf("   a   Cambiar fecha y hora de ultimo acceso\n");
printf("   f   Seleccionar el fichero de trabajo\n");
printf("   m   Cambiar fecha y hora de dltima modificaci\n\n");
printf("   o   Cambiar propietario del fichero\n");
printf("   p   Cambiar los permisos al fichero\n");
printf("   q   Salir de la utilidad\n");
printf("   s   Visualizar el estatus del fichero\n");
printf("   !   Ejecutar un comando UNIX\n");
printf("   ?   Visualizar esta ayuda\n");
}

static void prompt (char *msg, char *entrada)
{ printf("\n%s",msg);
if(gets(entrada)==NULL) exit(0);
}

static void status(char *path)  /* orden s */
{  struct stat sb;
if (stat(path,&sb)==-1)
  { perror("stat"); return; }
dspstatus(&sb);
}

static void dspstatus(struct stat *sbp)  /* mostrar el estatus */
{  short isdevice=0;
struct passwd *pw, *getpwuid();
struct group *gr,*getgrgid();
char *nombre,*asctime();
struct tm *localtime();
if ((sbp->st_mode & S_IFMT) == S_IFDIR)
      printf("Directorio\n");
if ((sbp->st_mode & S_IFMT) == S_IFBLK)
      { printf("Dispositivo Tipo Bloque\n");
      isdevice=1;  }
if ((sbp->st_mode & S_IFMT) == S_IFCHR)
      { printf("Dispositivo Tipo Car<cter\n");
      isdevice=1;  }
if ((sbp->st_mode & S_IFMT) == S_IFREG)
      printf("Fichero Ordinario\n");
if ((sbp->st_mode & S_IFMT) == S_IFIFO)
      printf("Fichero FIFO\n");
if (isdevice) printf("Dispositivo numero : %d, %d \n",
		  (sbp->st_rdev>>8)&0377,sbp->st_rdev&0377);
printf("Reside en el dispositivo numero : %d, %d \n",
		  (sbp->st_dev>>8)&0377,sbp->st_dev&0377);
printf("Ndmero de I-nodo: %d, Links: %d, TamaZo: %ld\n",
	    sbp->st_ino,sbp->st_nlink,sbp->st_size);
if ((pw=getpwuid(sbp->st_uid))==NULL) nombre="????";
else nombre=pw->pw_name;
printf("Propietario uid = %d; nombre = %s\n",sbp->st_uid,nombre);
if ((gr=getgruid(sbp->st_gid))==NULL) nombre="????";
else nombre=gr->gr_name;
printf("Grupo       gid = %d; nombre = %s\n",sbp->st_gid,nombre);
if ((sbp->st_mode & S_ISUID)==S_ISUID)
   printf("Set-user-ID activado\n");
if ((sbp->st_mode & S_ISGID)==S_ISGID)
   printf("Set-group-ID activado\n");
if ((sbp->st_mode & S_ISVTX)==S_ISVTX)
   printf("Salva del segmento de texto activadao\n");
printf("Permisos: %o\n",sbp->st_mode & 0777);
printf("Ultimo acceso .............: %s",
     asctime (localtime(&sbp->st_atime)));
printf("Ultima modificaci\n .......: %s",
     asctime (localtime(&sbp->st_mtime)));
printf("Ultimo cambio de estatus ..: %s",
     asctime (localtime(&sbp->st_ctime)));
}

static void chtime (path, orden) /* \rdenes "a" y "m" */
char *path, *orden;
{ char atime[20];
long seg,timecvt();
struct stat sb;
struct utimbuf {
   time_t actime;
   time_t modtime; } tb;
if (stat(path,&sb)==ERROR)
   { perror("stat");
   return; }
prompt ("Entre el valor del tiempo (YYMMDDhhmmss) :", atime=);
if ((seg=timecvt(atime)) <=0) return;
switch(orden)
   { case 'a': tb.actime=seg;
	       tb.modtime=sb.st_mtime;
	       break;
   case 'm':   tb.actime=sb.st_atime;
	       tb.modtime=seg;  }
if (utime(path,&tb)==ERROR) perror ("utime");
}

static void chowner (path) /* orden "o" */
char *path;
{ char oname[20],gname[20];
int owner,group;
struct passwd *pw, *getpwnam();
struct group *gr, *getgrnam();
prompt ("Nombre del propietario :",oname);
if ((pw=getpwnam(oname))==NULL)
    { printf("Nombre de propietario desconocido\n");
    return; }
owner=pw->pw_uid;
prompt ("Nombre del grupo :",gname);
if ((gr=getgrnam(gname))==NULL)
    { printf("Nombre de grupo desconocido\n");
    return; }
group=gr->gr_gid;
if (chown(path,owner,group)==ERROR) perror("chown");
return;
}

static void chperms (path) /* orden "p" */
char *path;
{ char smode[20];
int mode;
prompt ("Protecciones (en 4 digitos octales)", smode);
if (sscanf(smode,"%o",&mode)!=1)
   { printf("Modo invalido\n");
   return; }
if (chmod(path,mode)==ERROR)  perror("chmod");
return;
}

static long timecvt (atime)
char *atime;
/* Conversi\n de YYMMDDhhmmss a formato interno */
{ long tm;
int i,n,dias,zona;
char s[3], *getenv(),*tz;
int esbisiesto;
extern struct tm *localtime();
if (strlen(atime)!=12)
   { printf ("Fecha y hora en 12 digitos : YYMMDDhhmmss\n");
   return (0); }
for (i=0; i<12; i++)
  if (atime[i] <'0'|| atime[i] >'9')
     { printf"La fecha/hora tiene caracteres no numJricos\n");
     return (0); }
if ((tz=getenv("TZ"))==NULL)  zona=5;
else zona=atoi(&tz[3]);
s[2]='\0';
/* p<g 51 de Advanced UNIX Programming */
return;
}
	------------------------------



1


